﻿Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
Imports System.IO

Public Class BCliente

#Region "VARIABLES"
    Private Stm As Stream 'Utilizado para enviar datos al Servidor y recibir datos del mismo
    Private m_IPDelHost As String 'Direccion del objeto de la clase Servidor
    Private m_PuertoDelHost As String 'Puerto donde escucha el objeto de la clase Servidor
#End Region

#Region "EVENTOS"
    Public Event ConexionTerminada()
    Public Event DatosRecibidos(ByVal datos As String)
#End Region

#Region "PROPIEDADES"
    Public Property IPDelHost() As String
        Get
            IPDelHost = m_IPDelHost
        End Get
        Set(ByVal Value As String)
            m_IPDelHost = Value
        End Set
    End Property

    Public Property PuertoDelHost() As String
        Get
            PuertoDelHost = m_PuertoDelHost
        End Get
        Set(ByVal Value As String)
            m_PuertoDelHost = Value
        End Set
    End Property
#End Region

#Region "METODOS"

    'este método no devolvia nada era un SUB, pero como tenemos que controlar si la conexións e hace bien o no
    'uso un booleano para que devuelva si es OK o no la conexión.
    Public Function Conectar() As Boolean
        Dim estado As Boolean = True
        Dim tcpClnt As TcpClient 'Proporciona conexiones de cliente para servicios de red TCP
        Dim tcpThd As Thread 'Se encarga de escuchar mensajes enviados por el Servidor
        tcpClnt = New TcpClient()

        'PONER AQUI EXCEPCIÓN PARA CUANDO EL SERVER NO ESTÉ ARRANCADO TODAVÍA
        Try
            'Me conecto al objeto de la clase Servidor, determinado por las propiedades IPDelHost y PuertoDelHost
            tcpClnt.Connect(IPDelHost, PuertoDelHost)
            Stm = tcpClnt.GetStream()

            'Creo e inicio un thread para que escuche los mensajes enviados por el Servidor
            'al crear el nuevo objeto Thread le pasamos el método que queremos ejecutar.
            tcpThd = New Thread(AddressOf LeerSocket)
            tcpThd.Start()
        Catch ex As Exception
            'MsgBox(ex.Message)
            MsgBox("No se ha podido establecer la conexión con el Servidor." + ControlChars.Lf + "                      Causa: Servidor no encendido" + ControlChars.Lf + "                      Causa: IP Servidor erronea", MsgBoxStyle.Information, "Los Colonos de Catan informa:")
            estado = False
        End Try
        Return estado
    End Function

    Public Sub EnviarDatos(ByVal Datos As String)
        Dim BufferDeEscritura() As Byte

        BufferDeEscritura = Encoding.ASCII.GetBytes(Datos)

        'Compruebo que no sea nada lo que quiero enviar
        If Not (Stm Is Nothing) Then
            'Envio los datos al Servidor
            Stm.Write(BufferDeEscritura, 0, BufferDeEscritura.Length)
        End If
    End Sub

    Public Sub cerrarSocket()
        RaiseEvent ConexionTerminada()
    End Sub
    Public Sub cerrarSocket(ByVal cadena As String)
        Try
            EnviarDatos(cadena)
        Catch ex As Exception
            MsgBox("No se ha cerrado correctamente")
        End Try
    End Sub
#End Region

#Region "FUNCIONES PRIVADAS"
    Private Sub LeerSocket()
        Dim BufferDeLectura() As Byte
        While True
            Try
                BufferDeLectura = New Byte(100) {}
                'Me quedo esperando a que llegue algun mensaje
                Stm.Read(BufferDeLectura, 0, BufferDeLectura.Length)

                'Genero el evento DatosRecibidos, ya que se han recibido datos desde el Servidor
                'RaiseEvent= Desencadena un evento declarado en el nivel de módulo dentro de una clase, formulario o documento.
                RaiseEvent DatosRecibidos(Encoding.ASCII.GetString(BufferDeLectura))
            Catch e As Exception
                Exit While
            End Try
        End While

        'Finalizo la conexion, por lo tanto genero el evento correspondiente
        RaiseEvent ConexionTerminada()
    End Sub

#End Region
End Class
